home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / comm / revrdist.sit / RevRdist / RevRdist src / junkf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-15  |  7.3 KB  |  307 lines  |  [TEXT/KAHL]

  1. /*
  2.  * junkf.c - routines for manipulating the "junk" folder
  3.  */ 
  4. #include "RevRdist.h"
  5. #include "dispatch.h"
  6. #include <TransSkelProto.h>
  7. #include <TransDisplayProto.h>
  8.  
  9. /*
  10.  * prototype for local function
  11.  */
  12. static Integer testJunk(cnode_t *);
  13.  
  14. /*
  15.  *=========================================================================
  16.  * cleanJunk () - get rid of old files in "junk" folder
  17.  *=========================================================================
  18.  */
  19.  
  20. DISPATCHED (cleanJunk)
  21. {
  22.     struct lm                        /* local memory */
  23.     {
  24.         frame_t            f;
  25.     };
  26.     typedef struct lm    lm_t;
  27.     register lm_t *        m;            /* pointer to local memory */
  28.     OSErr                error;
  29.     file_info_t *        fi;            /* ptr to junk entry in File_list[] */
  30.     StringPtr            p;            /* temp */
  31.     Ptr                    paramv[2];
  32.     short                result;        /* our result */
  33.     StringHandle        sh;            /* temp */
  34.  
  35.     m = *(lm_t **)fh;
  36.     result = request;
  37.     error = 0;
  38.     switch (request)
  39.     {
  40.     case R_INIT:
  41.         if (ClueID = resizeFrame (fh, sizeof (lm_t)))
  42.             return R_ERROR;
  43.         m = *(lm_t **)fh;
  44.         m->f.state = 1;
  45.         return R_CONT;
  46.  
  47.     case R_CONT:
  48.         /*
  49.          * The bulk of the work is just setting up for emptyFolder.
  50.          * Everything is done in state 1.
  51.          */
  52.         fi = &File_list[FL_JUNK];
  53.         if (m->f.state == 1)
  54.         {
  55.             if (fi->f_vol == 0 || fi->f_set == 0)
  56.             {
  57.                 /*
  58.                  * Mention it if there is no junk folder
  59.                  */
  60.                 if (sh = Prefs[P_WORK].p[PS_JUNKF])
  61.                 {
  62.                     HLock ((Handle)sh);
  63.                     p = *sh;
  64.                 }
  65.                 else
  66.                     p = (SP) "\p<unknown>";
  67.                 dispIndStr (ActivityWind, L_SKIP, LST_STR, p, nil);
  68.                 result = R_CONT;
  69.                 if (sh)
  70.                     HUnlock ((Handle)sh);
  71.                 result = popCall (R_CONT, nil);
  72.                 break;
  73.             }
  74.             /*
  75.              * Tell 'em what we're doing
  76.              */
  77.             if (Flags & DB_VERBOSE)
  78.             {
  79.                 sh = fi->f_path;
  80.                 HLock ((Handle)sh);
  81.                 dispIndStr (ActivityWind, L_DOJUNK, LST_STR, *sh, nil);
  82.                 HUnlock ((Handle)sh);
  83.             }
  84.             /*
  85.              * Use the File_list catalog entry for junk folder for emptyFolder()
  86.              */
  87.             m->f.state = 2;
  88.             paramv[0] = (Ptr)&fi->f_info;
  89.             paramv[1] = (Ptr)testJunk;
  90.             return (pushCall (emptyFolder, paramv));
  91.         }
  92.         else if (m->f.state == 2)
  93.         {
  94.             m->f.state = 3;
  95.             return result;            /* just allow emptyFolder to exit */
  96.         }
  97.         /*
  98.          * Else, fall into
  99.          */
  100.     default:
  101.         result = popCall (result, nil);
  102.         break;
  103.     }
  104.     return result;
  105. }
  106.  
  107.  
  108.  
  109. /*
  110.  *=========================================================================
  111.  * makeJunk () - create junk folder
  112.  * entry:    junk folder name given by preferences string
  113.  * returns:    OSErr
  114.  *=========================================================================
  115.  */
  116.  
  117.  
  118. OSErr
  119. makeJunk ()
  120. {
  121.     OSErr                error;
  122.     file_info_t *        fi;            /* ptr into File_list for junk folder */
  123.     StringHandle        sh;            /* name of junk folder */
  124.     HParamBlockRec        hpb;        /* for PBDirCreate, etc */
  125.     Str255                s;            /* string temp */
  126.  
  127.     error = fnfErr;
  128.     s[0] = 0;
  129.     sh = Prefs[P_WORK].p[PS_JUNKF];
  130.     while (sh && **sh)                /* "while" is so can use "break" */
  131.     {
  132.         /*
  133.          * We always try to create the junk folder, even though that will
  134.          * often fail.  But it's just as fast as checking to see if the
  135.          * folder exists.
  136.          */
  137.         COPYPS (*sh, s);
  138.         ZERO (hpb);
  139.         hpb.fileParam.ioNamePtr = s;
  140.         hpb.fileParam.ioVRefNum = ClientVol;
  141.         hpb.fileParam.ioDirID = ClientRoot;
  142.         error = PBDirCreate (&hpb, false);
  143.         switch (error)
  144.         {
  145.         case noErr:                    /* folder created */
  146.             break;
  147.         case vLckdErr:                /* if volume locked, switch to LISTONLY */
  148.         case wPrErr:
  149.             Flags |= DB_LISTONLY;
  150.             /* fall into ... */
  151.         case dupFNErr:                /* if already exists, not an error */
  152.             error = 0;
  153.             break;
  154.         }
  155.         if (error)                    /* if trouble already */
  156.             break;
  157.         fi = &File_list[FL_JUNK];
  158.         fi->f_ref = 0;
  159.         fi->f_vol = ClientVol;
  160.         error = getInfoByPath (s, fi);
  161.         break;
  162.     }
  163.     if (error)
  164.     {
  165.         warning (E_NOJUNK, s, nil);
  166.         error = 0;
  167.     }
  168.     return error;
  169. }
  170.  
  171.  
  172.  
  173. /*
  174.  *=========================================================================
  175.  * moveToJunk (cp) - move file/folder to junk folder
  176.  * entry:    cp = pointer to client catalog list node
  177.  * returns:    0 on success, else OSErr
  178.  *=========================================================================
  179.  */
  180. OSErr
  181. moveToJunk (cp)
  182. register cnode_t *    cp;
  183. {
  184.     OSErr            error;
  185.     file_info_t *    fi;                    /* ptr to File_list for junk */
  186.     int                i,j;                /* temps */
  187.     char *            s;
  188.     CMovePBRec        cpb;                /* PBCatMove param block */
  189.     HParamBlockRec    pb;                    /* PBHRename param block */
  190.     Byte            junkname[32];        /* new name for existing junk file */
  191.  
  192.     fi = &File_list[FL_JUNK];
  193.     if (fi->f_set == 0)
  194.     {
  195.         /* if no junk directory, skip it */
  196.         notice (L_SKPJUNK, cp->name, nil);
  197.         return 0;
  198.     }
  199.     if (cp->dirID == fi->f_info.dirID)
  200.         return 0;                    /* cannot move junk into itself */
  201.     notice (L_JUNKING, cp->name, nil);
  202.     if (Flags & DB_LISTONLY)
  203.         return 0;
  204. retry:
  205.     ZERO (cpb);
  206.     cpb.ioNamePtr = cp->name;
  207.     cpb.ioVRefNum = ClientVol;
  208.     cpb.ioDirID = cp->parID;
  209.     cpb.ioNewName = fi->f_info.name;
  210.     cpb.ioNewDirID = fi->f_info.parID;
  211.     error = PBCatMove (&cpb, false);
  212.     s = "\pPBCatMove";
  213.     /*
  214.      * If the move fails, it might be because there is already something
  215.      * there by the same name.  If so, rename the existing file/folder
  216.      * and try moving again.
  217.      */
  218.     if (error == dupFNErr)
  219.     {
  220.         COPYPS (cp->name, junkname);
  221.         do
  222.         {
  223.             /*
  224.              * We try several possible names to rename the conflicting
  225.              * file/folder out of the way.
  226.              * The first is just to append the Junksuf string to the name.
  227.              * If that won't fit, we replace the end of the name with
  228.              * Junksuf.
  229.              * If the result still conflicts, we increment the last character
  230.              * of the name until we get no conflict or we run out of
  231.              * "nice" characters, where "nice" is defined as "differing
  232.              * from the last char of Junksuf only in the low 5 bits".
  233.              */
  234.             j = Junksuf[0];
  235.             i = junkname[0];
  236.             if (i < 31)
  237.             {
  238.                 if (i + j > 31)
  239.                     i = 31 - j;
  240.                 junkname[0] = i + j;
  241.                 for (;j;j--)
  242.                     junkname[i+j] = Junksuf[j];
  243.             }
  244.             else
  245.             {
  246.                 j = junkname[i];
  247.                 if ((j & 0x1f) != 0x1f)
  248.                     junkname[i] = j+1;
  249.                 else
  250.                     return error;
  251.             }
  252.             ZERO (pb);
  253.             pb.ioParam.ioNamePtr = cp->name;
  254.             pb.ioParam.ioVRefNum = ClientVol;
  255.             pb.ioParam.ioMisc = (Ptr) junkname;
  256.             pb.fileParam.ioDirID = fi->f_info.dirID;
  257.             error = PBHRename (&pb, false);
  258.             s = "\pPBHRename";
  259.         } while (error == dupFNErr);
  260.         if (error == 0)
  261.             goto retry;
  262.     }
  263.     if (error)
  264.     {
  265.         ClueID = error;
  266.         notice (L_SYS, (SP)"\pmoveToJunk", (SP) s, nil);
  267.     }
  268.     else
  269.         statMsgClr ();
  270.     return error;
  271. }
  272.  
  273.  
  274.  
  275. /*
  276.  *=========================================================================
  277.  * testJunk (cp) - decide if file/folder should be discarded from junk
  278.  * entry:    cp = pointer to catalog list entry for file/folder
  279.  *            Junkp, ClientSp set
  280.  * returns:    0 if file/folder should not be discarded
  281.  *            <> 0 if it should
  282.  *=========================================================================
  283.  */
  284. static
  285. Integer
  286. testJunk (cp)
  287. register cnode_t *    cp;
  288. {
  289. register Integer    result;
  290.     static unsigned long now = 0;
  291.  
  292.     if (now == 0)
  293.         GetDateTime ((long *)&now);
  294.     if (cp->ctype == C_FOLDER)
  295.         result = true;                /* always junk (contents of) folders */
  296.     else if (cp->mdDate + Prefs[P_WORK].p_jparam.max < now)
  297.         result = true;                /* if modified long ago */
  298.     else if (cp->mdDate + Prefs[P_WORK].p_jparam.min > now)
  299.         result = false;                /* if changed recently */
  300.     else if (ClientSp < Prefs[P_WORK].p_jparam.space)
  301.         result = true;                /* if short on space */
  302.     else
  303.         result = false;
  304.     if (result && cp->ctype == C_FILE)
  305.         ClientSp += (cp->in.f.fileLen + cp->in.f.rsrcLen);
  306.     return result;
  307. }